#include "I2C.h"
#include "string.h"

extern unsigned char I2C_DeviceNum ;

void HardWare_I2C2_Init(){
	
	GPIO_InitTypeDef GPIO_InitStructure ;
	I2C_InitTypeDef I2C_InitStructure ;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
	
	RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2,ENABLE);
	RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2,DISABLE);
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2,ENABLE);

	GPIO_PinAFConfig(GPIOB,GPIO_PinSource8,GPIO_AF_I2C2);
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource9,GPIO_AF_I2C2);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                                   
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8| GPIO_Pin_9;
	 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
	I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
	I2C_InitStructure.I2C_ClockSpeed = 400000;
	I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_16_9;
	I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
	I2C_InitStructure.I2C_OwnAddress1 = 0x00;
	
	I2C_Init(I2C2,&I2C_InitStructure);
	
	I2C_Cmd(I2C2,ENABLE);

}

void I2C2_WriteByte(uint8_t address,uint8_t addr,uint8_t data)
{
		while( I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY) );
		I2C_GenerateSTART(I2C2, ENABLE);
		
		while( !I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) );
		I2C_Send7bitAddress(I2C2, address, I2C_Direction_Transmitter);
		
		while( !I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) );
		I2C_SendData(I2C2, addr);
		
		while( !I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING) );
		I2C_SendData(I2C2, data);
		
		while( !I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED) );
		I2C_GenerateSTOP(I2C2, ENABLE);
}


void I2C2_Device_Scanner(unsigned char * address){
	
		unsigned char i = 0 ,next = 0;
		int timeout  = 0 ;
		I2C_DeviceNum = 0;
		memset(address,0,128);

		for(; i <0xff>>1 ; i++){
			
			timeout  = 0 ;
			while( I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY&&timeout<=10000) ){timeout++ ;};
			if(timeout>9999)
				continue;
			I2C_GenerateSTART(I2C2, ENABLE);
			
			
			timeout  = 0 ;
			while( (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)&&timeout<=10000) ){timeout++;};
			if(timeout>9999)
				continue;
			
			timeout  = 0 ;
			I2C_Send7bitAddress(I2C2, i<<1 , I2C_Direction_Transmitter);
			
			while( (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)&&timeout<=10000) ){timeout++;};
			if(timeout>9999)
				continue;
			I2C_SendData(I2C2, 0x00);
			
			while( !I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING) );
			I2C_SendData(I2C2, 0x00);
			
			while( !I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED) );
			
			I2C_GenerateSTOP(I2C2, ENABLE);
			
			I2C_DeviceNum++;
			
			address[next] = i<<1 ;			/*attention 8 bit !*/
			next++;
		}
		
		HardWare_I2C2_Init();					/*you have to reset i2c bus to reset all pin or the i2c bus can t work successfully*/
}


unsigned char  I2C2_ByteRead(unsigned char DeviceAddress,unsigned char ReadAddr)
{
	uint8_t Buffer;
	
	 while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));
	I2C_GenerateSTART(I2C2,ENABLE);
	//check EV5
	while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT) == ERROR);

	I2C_Send7bitAddress(I2C2,DeviceAddress,I2C_Direction_Transmitter);

	//check EV6
	while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) == ERROR);

	I2C_SendData(I2C2, ReadAddr);
	//check EV8_2
	while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED) == ERROR);

	
	
	I2C_GenerateSTART(I2C2,ENABLE);
	//check EV5
	while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT) == ERROR);
	
	I2C_Send7bitAddress(I2C2,DeviceAddress,I2C_Direction_Receiver);
	//check EV6
	while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) == ERROR);

	I2C_AcknowledgeConfig(I2C2,DISABLE);
	I2C_GenerateSTOP(I2C2,ENABLE);
	//check EV7
	while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_BYTE_RECEIVED) == ERROR);
	Buffer = I2C_ReceiveData(I2C2);
	
	I2C_AcknowledgeConfig(I2C2,DISABLE);
	
	return Buffer;
	
}
